package org.lds.message.center.admin.business.channel.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.lds.message.center.admin.business.channel.converter.*;
import org.lds.message.center.admin.business.channel.entity.Channel;
import org.lds.message.center.admin.business.channel.mapper.ChannelMapper;
import org.lds.message.center.admin.business.channel.model.request.*;
import org.lds.message.center.admin.business.channel.model.response.*;
import org.lds.message.center.admin.business.channel.service.ChannelBaseService;
import org.lds.message.center.common.model.ResultDTO;
import org.lds.message.center.common.model.db.OrderBy;
import org.lds.message.center.common.model.db.PageResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 基础服务实现类
 *
 * @author lidongsheng
 * @since 2024-12-22
 */
@Slf4j
@Service
public class ChannelBaseServiceImpl implements ChannelBaseService {

    @Autowired
    private ChannelMapper channelMapper;

    @Autowired
    private ChannelBaseCreateRequestToEntityConverter channelBaseCreateRequestToEntityConverter;

    @Autowired
    private ChannelBaseUpdateRequestToEntityConverter channelBaseUpdateRequestToEntityConverter;

    @Autowired
    private ChannelBaseListRequestToEntityConverter channelBaseListRequestToEntityConverter;

    @Autowired
    private ChannelToBaseResponseConverter channelToBaseResponseConverter;

    @Autowired
    private ChannelBaseListPageRequestToEntityConverter channelBaseListPageRequestToEntityConverter;

    @Autowired
    private ChannelBaseGetByKeyRequestToEntityConverter channelBaseGetByKeyRequestToEntityConverter;

    @Autowired
    private ChannelBaseDeleteRequestToEntityConverter channelBaseDeleteRequestToEntityConverter;

    @Override
    @Transactional
    public ResultDTO<ChannelBaseResponse> createChannel(ChannelBaseCreateRequest request) {
        try {
            Channel channel = channelBaseCreateRequestToEntityConverter.convert(request);
            channelMapper.insert(channel);
            ChannelBaseResponse response = channelToBaseResponseConverter.convert(channel);
            return ResultDTO.success(response);
        } catch (DuplicateKeyException e) {
            return ResultDTO.fail("DATA_REPEAT", "数据重复");
        }
    }

    @Transactional
    @Override
    public ResultDTO<ChannelBaseBatchCreateResponse> batchCreateChannel(ChannelBaseBatchCreateRequest request) {
        ChannelBaseBatchCreateResponse response = ChannelBaseBatchCreateResponse.builder()
                .responses(request.getRequests().stream().map(this::createChannel).collect(Collectors.toList()))
                .build();
        return ResultDTO.success(response);
    }

    @Transactional
    @Override
    public ResultDTO<ChannelBaseDeleteResponse> deleteChannel(ChannelBaseDeleteRequest request) {
        channelMapper.updateById(Channel.builder().id(request.getId()).enable(false).build());

        ChannelBaseDeleteResponse response = ChannelBaseDeleteResponse.builder()
                .request(request)
                .build();
        return ResultDTO.success(response);
    }

    @Transactional
    @Override
    public ResultDTO<ChannelBaseBatchDeleteResponse> batchDeleteChannel(ChannelBaseBatchDeleteRequest request) {
        ChannelBaseBatchDeleteResponse response = ChannelBaseBatchDeleteResponse.builder()
                .responses(request.getRequests().stream().map(this::deleteChannel).collect(Collectors.toList()))
                .build();
        return ResultDTO.success(response);
    }

    @Transactional
    @Override
    public ResultDTO<ChannelBaseResponse> updateChannel(ChannelBaseUpdateRequest request) {
        try {
            Channel channel = channelBaseUpdateRequestToEntityConverter.convert(request);
            channelMapper.updateById(channel);
            ChannelBaseResponse response = channelToBaseResponseConverter.convert(channel);
            return ResultDTO.success(response);
        } catch (DuplicateKeyException e) {
            return ResultDTO.fail("DATA_REPEAT", "数据重复");
        }
    }

    @Transactional
    @Override
    public ResultDTO<ChannelBaseBatchUpdateResponse> batchUpdateChannel(ChannelBaseBatchUpdateRequest request) {
        ChannelBaseBatchUpdateResponse response = ChannelBaseBatchUpdateResponse.builder()
                .requests(request.getRequests().stream().map(this::updateChannel).collect(Collectors.toList()))
                .build();
        return ResultDTO.success(response);
    }

    @Override
    public ResultDTO<ChannelBaseResponse> getChannelById(ChannelBaseGetByIdRequest request) {
        Channel channel = channelMapper.selectById(request.getId());
        if (channel == null) {
            return ResultDTO.success();
        }

        ChannelBaseResponse response = channelToBaseResponseConverter.convert(channel);
        return ResultDTO.success(response);
    }

    @Override
    public ResultDTO<ChannelBaseListResponse> getChannelByIds(ChannelBaseGetByIdsRequest request) {
        List<Channel> list = request.getIds().stream().map(id -> channelMapper.selectById(id)).collect(Collectors.toList());
        return ResultDTO.success(ChannelBaseListResponse.builder()
                .channels(list.stream().map(channel -> channelToBaseResponseConverter.convert(channel)).collect(Collectors.toList()))
                .build());
    }

    @Override
    public Channel getChannelByKey(ChannelBaseGetByKeyRequest request) {
        if (request == null) return null;
        if (!request.isHasBusinessKey()) return null;
        return channelMapper.selectOne(new QueryWrapper<>(channelBaseGetByKeyRequestToEntityConverter.convert(request)));
    }

    @Override
    public ResultDTO<ChannelBaseListResponse> listChannel(ChannelBaseListRequest request) {
        QueryWrapper<Channel> wrapper = new QueryWrapper<>(channelBaseListRequestToEntityConverter.convert(request));
        if (StringUtils.isNotEmpty(request.getOrderByKey())) {
            wrapper.orderByDesc(request.getOrderByKey());
        }

        List<Channel> channels = channelMapper.selectList(wrapper);

        ChannelBaseListResponse response = ChannelBaseListResponse.builder()
                .channels(channels.stream().map(channelToBaseResponseConverter::convert).collect(Collectors.toList()))
                .build();
        return ResultDTO.success(response);
    }

    @Override
    public ResultDTO<ChannelBaseListResponse> listAllChannel(OrderBy orderBy) {
        ChannelBaseListRequest channelRequest = ChannelBaseListRequest.builder().build();
        channelRequest.setOrderByKey(orderBy.getOrderByKey());
        return listChannel(channelRequest);
    }

    @Override
    public ResultDTO<PageResult<ChannelBaseResponse>> listChannelPage(ChannelBaseListPageRequest request) {
        Page<Channel> page = new Page<>(request.getPageNum(), request.getPageSize(), true);

        QueryWrapper<Channel> wrapper = new QueryWrapper<>(channelBaseListPageRequestToEntityConverter.convert(request));
        if (StringUtils.isNotEmpty(request.getOrderByKey())) {
            if (request.getOrderByDesc() != null && request.getOrderByDesc().booleanValue() == false) {
                wrapper.orderByAsc(request.getOrderByKey());
            } else {
                wrapper.orderByDesc(request.getOrderByKey());
            }
        }

        IPage<Channel> pageResult = channelMapper.selectPage(page, wrapper);

        PageResult<ChannelBaseResponse> response = new PageResult(
                pageResult.getTotal(), pageResult.getPages(), pageResult.getCurrent(), pageResult.getSize(),
                pageResult.getRecords().stream().map(channelToBaseResponseConverter::convert).collect(Collectors.toList()));
        return ResultDTO.success(response);
    }

    @Override
    public ResultDTO<ChannelBaseBatchCreateResponse> batchCreateChannelAsync(ChannelBaseBatchCreateRequest request) {
        ChannelBaseBatchCreateResponse response = ChannelBaseBatchCreateResponse.builder()
                .responses(request.getRequests().parallelStream().map(this::createChannel).collect(Collectors.toList()))
                .build();
        return ResultDTO.success(response);
    }

    @Override
    public ResultDTO<ChannelBaseBatchDeleteResponse> batchDeleteChannelAsync(ChannelBaseBatchDeleteRequest request) {
        ChannelBaseBatchDeleteResponse response = ChannelBaseBatchDeleteResponse.builder()
                .responses(request.getRequests().parallelStream().map(this::deleteChannel).collect(Collectors.toList()))
                .build();
        return ResultDTO.success(response);
    }

    @Override
    public ResultDTO<ChannelBaseBatchUpdateResponse> batchUpdateChannelAsync(ChannelBaseBatchUpdateRequest request) {
        ChannelBaseBatchUpdateResponse response = ChannelBaseBatchUpdateResponse.builder()
                .requests(request.getRequests().parallelStream().map(this::updateChannel).collect(Collectors.toList()))
                .build();
        return ResultDTO.success(response);
    }

}
